home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / smath.cq / strmath.c
C/C++ Source or Header  |  1985-06-03  |  29KB  |  1,052 lines

  1. /*
  2.  *    Program name:  strmath.c
  3.  *    
  4.  *    Program author:  Robert E. Sawyer
  5.  *                     Torrance, California
  6.  *
  7.  *    Released for personal, non-commercial use only, 1 August 1984.
  8.  *
  9.  *    Specifications to which the main functions were written:
  10.  *        They must do decimal arithmetic on numbers stored in strings.
  11.  *        The numbers must be in the form:
  12.  *           
  13.  *        Snnnnnnn.nnnn
  14.  *         
  15.  *        where "S" is an optional sign (+ or -), "n" is any
  16.  *        decimal digit (0 through 9) and "." is an optional
  17.  *        decimal point.  The four routines should be called
  18.  *        "decadd", "decsub", "decmul", and "decdiv", and they
  19.  *        each must be called as follows:
  20.  *        
  21.  *                char n1[21],n2[21],result[21];
  22.  *                strcpy (n1,"123.45");
  23.  *                strcpy (n2,"-3.0)";
  24.  *        
  25.  *                if (!decadd(result,n1,n2))
  26.  *                    printf ("Error adding %s to %s\n", n1, n2);
  27.  *                else
  28.  *                    printf ("Result is %s\n", result);
  29.  *        
  30.  *        In this example, the program should print
  31.  *        
  32.  *                Result is 120.45
  33.  *        
  34.  *        "decsub", "decmul", and "decdiv" should work the same
  35.  *        way.
  36.  *        
  37.  *        These routines should return a 1 (true) if the arguments
  38.  *        are valid and the result can be calculated, and a 0
  39.  *        (false) if anything is wrong.  In the case of an error,
  40.  *        the "result" argument should contain a null value.
  41.  *        
  42.  *        The strings may have from 1 to 18 significant digits.
  43.  *        Since there can be a leading sign and a decimal point,
  44.  *        the strings must be able to hold at least 20 characters.
  45.  *        They are dimensioned with 21 above to handle the 20
  46.  *        character limit plus the trailing zero needed in C
  47.  *        strings.
  48.  *        
  49.  *        If the result will be too long (i.e. more than 18
  50.  *        significant digits) treat that case as an error
  51.  *        (i.e., return a 0 and set "result" to be a null).
  52.  *        The same holds true for an attempted division by zero.  
  53.  *        
  54.  *        Math must be EXACT (!!) -- that means no rounding!
  55.  *        These routines must run on an IBM PC without an
  56.  *        8087 chip, and they must be written using only
  57.  *        C functions (i.e., no "C Tools", "C Food", or
  58.  *        other enhancement packages).
  59.  *
  60.  *    Sources:  The lowest level string-math functions are modelled
  61.  *        on corresponding algorithms in D.E.Knuth's, 'The Art of
  62.  *        Computer Programming', Vol.2, and on C.E.Burton's algorithms
  63.  *        in DDJ, #89, 'RSA: A Public Key Cryptosystem, Part 1'.
  64.  */
  65.  
  66. #define N    18     /*chosen maximum number of significant digits */
  67. #define MIN(x, y)  ((x) > (y) ? (y) : (x))
  68. #define MAX(x, y)  ((x) > (y) ? (x) : (y))
  69.  
  70. /*-----------------driver to test the functions-------------------*/
  71. main()                
  72.     {
  73.     char n1[N+3], n2[N+3], nn1[N+3], nn2[N+3], res1[N+3], res2[N+3];
  74.     int l1, l2, lr1, lr2, ok;
  75.     char msg[N+3];
  76.  
  77.     printf("Arithmetic to %.0d significant digits\n\n", N);
  78.     while (1)
  79.         {
  80.         printf("Enter 1st number:  ");
  81.         scanf("%s", nn1);
  82.  
  83.          printf("Enter 2nd number:  ");
  84.         scanf("%s", nn2);
  85.  
  86.         l1 = strlen(nn1);
  87.         l2 = strlen(nn2);
  88.  
  89.         strcpy(n1, nn1);
  90.         strcpy(n2, nn2);
  91.         
  92.         ok = decadd(res1, n1, n2);
  93.         if (!ok)
  94.             strcpy(msg, "*ERROR*");
  95.         else
  96.             msg[0] = '\0';
  97.         printf("\n ADD -> %s  %s\n", res1, msg);
  98.  
  99.         ok = decsub(res1, n1, n2);
  100.         if (!ok)
  101.             strcpy(msg, "*ERROR*");
  102.         else
  103.             msg[0] = '\0';
  104.         printf("\n SUB -> %s  %s\n", res1, msg);
  105.  
  106.         ok = decmul(res1, n1, n2);
  107.         if (!ok)
  108.             strcpy(msg, "*ERROR*");
  109.         else
  110.             msg[0] = '\0';
  111.         printf("\n MUL -> %s  %s\n", res1, msg);
  112.  
  113.         ok = decdiv(res1, n1, n2);
  114.         if (!ok)
  115.             strcpy(msg, "*ERROR*");
  116.         else
  117.             msg[0] = '\0';
  118.         printf("\n DIV -> %s  %s\n", res1, msg);
  119.  
  120.         printf("-------------\n");
  121.         }
  122.     }
  123.  
  124. /*---------------------main functions--------------------------*/
  125.  
  126. decadd(sum, n1, n2)
  127.     char sum[], n1[], n2[];
  128.     {
  129.     char num[N+3], num1[N+3], num2[N+3];
  130.     int sign1, digl1, digr1, sign2, digl2, digr2;
  131.     int sign, digr;
  132.     int len, len1, len2;
  133.     int del;
  134.  
  135.     if (parse(n1, num1, &sign1, &digl1, &digr1) &&
  136.         parse(n2, num2, &sign2, &digl2, &digr2))
  137.         {
  138.         len1 = strlen(num1);
  139.         len2 = strlen(num2);
  140.         len  = MAX(digl1, digl2) + MAX(digr1, digr2);
  141.         if (len > N)    /* allow for sign, decimal point, and '\0' */
  142.             {
  143.             sum[0] = '\0';
  144.             return (0);
  145.             }
  146.         if (digr1 < digr2)
  147.             {
  148.             del = digr2 - digr1;
  149.             pad(num1, del);
  150.             len1 += del;
  151.             digr = digr2;
  152.             } 
  153.         else
  154.             {
  155.             del = digr1 - digr2;
  156.             pad(num2, del);
  157.             len2 += del;
  158.             digr = digr1;
  159.             }
  160.         if (!add(num1, len1, sign1, num2, len2, sign2, num, &sign))
  161.             {
  162.             sum[0] = '\0';
  163.                 return (0);
  164.             }
  165.         if ((len = strlen(num)) > N)
  166.             {
  167.             sum[0] = '\0';
  168.             return (0);
  169.             }
  170.         fix(num, len, sign, digr);
  171.         strcpy(sum, num);
  172.         return (1);
  173.         }
  174.     else
  175.         {
  176.         sum[0] = '\0';
  177.         return (0);
  178.         }
  179.     }
  180.  
  181. decsub(dif, n1, n2)
  182.     char dif[], n1[], n2[];
  183.     {
  184.     char num[N+3], num1[N+3], num2[N+3];
  185.     int sign1, digl1, digr1, sign2, digl2, digr2;
  186.     int sign, digr;
  187.     int len, len1, len2;
  188.     int del;
  189.  
  190.     if (parse(n1, num1, &sign1, &digl1, &digr1) &&
  191.         parse(n2, num2, &sign2, &digl2, &digr2))
  192.         {
  193.         len1 = strlen(num1);
  194.         len2 = strlen(num2);
  195.         len  = MAX(digl1, digl2) + MAX(digr1, digr2);
  196.         if (len > N)    /* allow for sign, decimal point, and '\0' */
  197.             {
  198.             dif[0] = '\0';
  199.             return (0);
  200.             }
  201.         if (digr1 < digr2)
  202.             {
  203.             del = digr2 - digr1;
  204.             pad(num1, del);
  205.             len1 += del;
  206.             digr = digr2;
  207.             } 
  208.         else
  209.             {
  210.             del = digr1 - digr2;
  211.             pad(num2, del);
  212.             len2 += del;
  213.             digr = digr1;
  214.             }
  215.         if (!sub(num1, len1, sign1, num2, len2, sign2, num, &sign))
  216.             {
  217.             dif[0] = '\0';
  218.             return (0);
  219.             }
  220.         if ((len = strlen(num)) > N)
  221.             {
  222.             dif[0] = '\0';
  223.             return (0);
  224.             }
  225.         fix(num, len, sign, digr);
  226.         strcpy(dif, num);
  227.         return (1);
  228.         }
  229.     else
  230.         {
  231.         dif[0] = '\0';
  232.         return (0);
  233.         }
  234.     }
  235.  
  236. decmul(prod, n1, n2)
  237.     char prod[], n1[], n2[];
  238.     {
  239.     char num[N+3], num1[N+3], num2[N+3];
  240.     int sign1, digl1, digr1, sign2, digl2, digr2;
  241.     int sign, digr;
  242.     int len, len1, len2;
  243.  
  244.     if (parse(n1, num1, &sign1, &digl1, &digr1) &&
  245.         parse(n2, num2, &sign2, &digl2, &digr2))
  246.         {
  247.         len1 = strlen(num1);
  248.         len2 = strlen(num2);
  249.         if (len1+len2-1 > N)    /* allow for sign, decimal point, and '\0' */
  250.             {
  251.             prod[0] = '\0';
  252.             return (0);
  253.             }
  254.         digr = digr1 + digr2;
  255.         if (!mul(num1, len1, sign1, num2, len2, sign2, num, &sign))
  256.             {
  257.             prod[0] = '\0';
  258.             return (0);
  259.             }
  260.         if ((len = strlen(num)) > N)
  261.             {
  262.             prod[0] = '\0';
  263.             return (0);
  264.             }
  265.         fix(num, len, sign, digr);
  266.         strcpy(prod, num);
  267.         return (1);
  268.         }
  269.     else
  270.         {
  271.         prod[0] = '\0';
  272.         return (0);
  273.         }
  274.     }
  275.  
  276. decdiv(quot, n1, n2)          
  277.     char quot[], n1[], n2[];
  278.     {
  279.     char num[N+N+1], num1[N+N+1], num2[N+3];
  280.     int sign1, digl1, digr1, sign2, digl2, digr2;
  281.     int sign, digr, digl, inum;
  282.     int len, len1, len2;
  283.  
  284.     if (parse(n1, num1, &sign1, &digl1, &digr1) &&
  285.         parse(n2, num2, &sign2, &digl2, &digr2))
  286.         {
  287.         len1 = strlen(num1);
  288.         len2 = strlen(num2);
  289.         pad(num1, N+N-len1);
  290.         if (!div(num1, N+N, sign1, num2, len2, sign2, num, &sign))
  291.             {
  292.             quot[0] = '\0';
  293.             return (0);
  294.             }
  295.         if ((len=strlen(num))==N+N-len2)
  296.             digl = len1 - len2;
  297.         else
  298.             digl = len1 - len2 + 1;
  299.         for (inum=len-1; (num[inum]=='0') && (inum>0); --inum)
  300.             ;
  301.         num[++inum] = '\0';
  302.         len = inum;
  303.         digr = len - digl + digr1 - digr2;
  304.         if ((len > N) || (digr > N) || (digl > N))
  305.             {
  306.             quot[0] = '\0';
  307.             return (0);
  308.             }
  309.         fix(num, len, sign, digr);
  310.         strcpy(quot, num);
  311.         return (1);
  312.         }
  313.     else
  314.         {
  315.         quot[0] = '\0';
  316.         return (0);
  317.         }
  318.     }
  319.  
  320. /*-----------intermediate level string-math functions----------*/
  321.  
  322. /*    add()
  323.  *    performs the appropriate string math
  324.  */
  325. add(num1, len1, sign1, num2, len2, sign2, num, sign)
  326.     char num1[], num2[], num[];
  327.     int sign1, sign2, *sign;
  328.     int len1, len2;
  329.     {
  330.     if ((sign1>0) && (sign2>0))
  331.         {
  332.         *sign = 1;
  333.         if (!sadd(num1, len1, num2, len2, num))
  334.             return (0);
  335.         }
  336.     else if ((sign1<0) && (sign2<0))
  337.         {
  338.         *sign = -1;
  339.         if (!sadd(num1, len1, num2, len2, num))
  340.             return (0);
  341.         }
  342.     else if ((sign1<0) && (sign2>0))
  343.         {
  344.         if ((len2>len1) || ((len2==len1) && (strcmp(num2,num1) > 0)))
  345.             {
  346.             *sign = 1;
  347.             if (!ssub(num2, len2, num1, len1, num))
  348.                 return (0);
  349.             }
  350.         else
  351.             {
  352.             *sign = -1;
  353.             if (!ssub(num1, len1, num2, len2, num))
  354.                 return (0);
  355.             }
  356.         }
  357.     else 
  358.         {
  359.         if ((len2>len1) || ((len2==len1) && (strcmp(num2,num1) > 0)))
  360.             {
  361.             *sign = -1;
  362.             if (!ssub(num2, len2, num1, len1, num))
  363.                 return (0);
  364.             }
  365.         else
  366.             {
  367.             *sign = 1;
  368.             if (!ssub(num1, len1, num2, len2, num))
  369.                 return (0);
  370.             }
  371.         }
  372.     return (1);
  373.     }
  374.  
  375. /*    sub()
  376.  *    performs the appropriate string math
  377.  */
  378. sub(num1, len1, sign1, num2, len2, sign2, num, sign)
  379.     char num1[], num2[], num[];
  380.     int sign1, sign2, *sign;
  381.     int len1, len2;
  382.     {
  383.     if ((sign1>0) && (sign2>0))
  384.         {
  385.         if ((len2>len1) || ((len2==len1) && (strcmp(num2,num1) > 0)))
  386.             {
  387.             *sign = -1;
  388.             if (!ssub(num2, len2, num1, len1, num))
  389.                 return (0);
  390.             }
  391.         else
  392.             {
  393.             *sign = 1;
  394.             if (!ssub(num1, len1, num2, len2, num))
  395.                 return (0);
  396.             }
  397.         }
  398.     else if ((sign1<0) && (sign2<0))
  399.         {
  400.         if ((len2>len1) || ((len2==len1) && (strcmp(num2,num1) > 0)))
  401.             {
  402.             *sign = 1;
  403.              if (!ssub(num2, len2, num1, len1, num))
  404.                 return (0);
  405.             }
  406.         else
  407.             {
  408.             *sign = -1;
  409.             if (!ssub(num1, len1, num2, len2, num))
  410.                 return (0);
  411.             }
  412.         }
  413.     else if ((sign1<0) && (sign2>0))
  414.         {
  415.         *sign = -1;
  416.         if (!sadd(num2, len2, num1, len1, num))
  417.             return (0);
  418.         }
  419.     else 
  420.         {
  421.         *sign = 1;
  422.         if (!sadd(num1, len1, num2, len2, num))
  423.             return (0);
  424.         }
  425.     return (1);
  426.     }
  427.  
  428. /*    mul()
  429.  *    performs the appropriate string math
  430.  */
  431. mul(num1, len1, sign1, num2, len2, sign2, num, sign)
  432.     char num1[], num2[], num[];
  433.     int sign1, sign2, *sign;
  434.     int len1, len2;
  435.     {
  436.     if (sign1*sign2 > 0)
  437.         {
  438.         *sign = 1;
  439.         if (!smul(num1, len1, num2, len2, num))
  440.             return (0);
  441.         }
  442.     else 
  443.         {
  444.         *sign = -1;
  445.         if (!smul(num1, len1, num2, len2, num))
  446.             return (0);
  447.         }
  448.     return (1);
  449.     }
  450.  
  451. /*    div()
  452.  *    performs the appropriate string math
  453.  */
  454. div(num1, len1, sign1, num2, len2, sign2, num, sign)
  455.     char num1[], num2[], num[];
  456.     int sign1, sign2, *sign;
  457.     int len1, len2;
  458.     {
  459.     char rem[N+3];
  460.  
  461.     if (sign1*sign2 > 0)
  462.         {
  463.         *sign = 1;
  464.         if (!sdiv(num1, len1, num2, len2, num, rem))
  465.             return (0);
  466.         if (rem[0] > '0')
  467.             return (0);
  468.         }
  469.     else 
  470.         {
  471.         *sign = -1;
  472.         if (!sdiv(num1, len1, num2, len2, num, rem))
  473.             return (0);
  474.         if (rem[0] > '0')
  475.             return (0);
  476.         }
  477.     return (1);
  478.     }
  479.  
  480. /*-----------lowest level string-math functions------------*/
  481.  
  482. /*  sadd(), ssub(), smul(), sdiv() perform the lowest level
  483.  *  manipulations on strings interpreted as nonnegative integers.
  484.  *    leading '0's are removed from num1, num2, and from the result
  485.  *  substrings, to which a terminal null is appended;
  486.  *    each function returns 0 on error.
  487.  */
  488.  
  489. /* sadd() yields sum[], 
  490.  * lens <= max(len1, len2) + 1  
  491.  */
  492. sadd(num1, len1, num2, len2, sum)
  493.     char num1[], num2[], sum[];
  494.     int len1, len2;
  495.     {
  496.     int lens, add, carry, index1, index2, indexs, temp1, temp2;
  497.  
  498.     lens = MAX(len1, len2) + 1;
  499.     indexs = lens - 1;
  500.     index1 = len1 - 1;
  501.     index2 = len2 - 1;
  502.     carry = 0;
  503.     while ( MIN(index1, index2) >= 0)
  504.         {
  505.         temp1 = num1[index1] - '0';
  506.         temp2 = num2[index2] - '0';
  507.         add = carry + temp1 + temp2;
  508.         sum[indexs] = add % 10 + '0';
  509.         carry = add / 10;
  510.         --index1;
  511.         --index2;
  512.         --indexs;
  513.         }
  514.     if (index2 < 0)
  515.         {
  516.         while (index1 >= 0)
  517.             {
  518.             temp1 = num1[index1] - '0';
  519.             add = carry + temp1;
  520.             sum[indexs] = add % 10 + '0';
  521.             carry = add / 10;
  522.             --index1;
  523.             --indexs;
  524.             }
  525.         }
  526.     else
  527.         {
  528.         while (index2 >= 0)
  529.             {
  530.             temp1 = num2[index2] - '0';
  531.             add = carry + temp1;
  532.             sum[indexs] = add % 10 + '0';
  533.             carry = add / 10;
  534.             --index2;
  535.             --indexs;
  536.             }
  537.         }
  538.     sum[indexs] = carry + '0';
  539.     --indexs;
  540.     while (indexs >= 0)
  541.         {
  542.         sum[indexs] = '0';
  543.         --indexs;
  544.         }
  545.     while ((sum[0]=='0') && (lens>1))
  546.         {
  547.         for (indexs=1; indexs<lens; ++indexs)
  548.             sum[indexs-1] = sum[indexs];
  549.         --lens;
  550.         }
  551.     sum[lens] = '\0';
  552.     return lens;
  553.     }
  554.  
  555. /* ssub() yields dif[], 
  556.  * lend <= len1
  557.  */        
  558. ssub(num1, len1, num2, len2, dif)
  559.     char num1[], num2[], dif[];
  560.     int len1, len2;
  561.     {
  562.     int lend, sub, borrow, index1, index2, indexd, temp1, temp2;
  563.  
  564.     lend = len1;
  565.     if (len1>=len2)
  566.         {
  567.         indexd = lend - 1;
  568.         index1 = len1 - 1;
  569.         index2 = len2 - 1;
  570.         borrow = 0;
  571.  
  572.         while (index2 >= 0)
  573.             {
  574.             temp1 = num1[index1] - '0';
  575.             temp2 = num2[index2] - '0';
  576.             sub = borrow + temp1 - temp2;
  577.             if (sub < 0)
  578.                 {
  579.                 sub += 10;
  580.                 borrow = -1;
  581.                 }
  582.             else
  583.                 borrow = 0;
  584.             dif[indexd] = sub + '0';
  585.             --index1;
  586.             --index2;
  587.             --indexd;
  588.             }
  589.         while (index1 >= 0)
  590.             {
  591.             temp1 = num1[index1] - '0';
  592.             sub = borrow + temp1;
  593.             if (sub < 0)
  594.                 {
  595.                 sub += 10;        
  596.                 borrow = -1;
  597.                 }
  598.             else
  599.                 borrow = 0;
  600.             dif[indexd] = sub + '0';
  601.             --index1;
  602.             --indexd;
  603.             }
  604.         if (borrow==0)
  605.             while (indexd >= 0)
  606.                 {
  607.                 dif[indexd] = '0';
  608.                 --indexd;
  609.                 }
  610.         else
  611.             {
  612.             dif[0] = '\0';
  613.             return 0;
  614.             }
  615.         while ((dif[0]=='0') && (lend>1))
  616.             {
  617.             for (indexd=1; indexd<lend; ++indexd)
  618.                 dif[indexd-1] = dif[indexd];
  619.             --lend;
  620.             }
  621.         dif[lend] = '\0';
  622.         }
  623.     else
  624.         {
  625.         dif[0] = '\0';
  626.         return 0;
  627.         }
  628.     return lend;
  629.     }
  630.  
  631. /* smul() yields prod[], 
  632.  * lenp <= len1 + len2 
  633.  */
  634. smul(num1, len1, num2, len2, prod)
  635.     char num1[], num2[], prod[];
  636.     int len1, len2;
  637.     {
  638.     int lenp, mult, carry, index1, index2, indexp, temp1, temp2, tempp;
  639.  
  640.     lenp = len1 + len2;
  641.     index2 = len2 - 1;
  642.     for (indexp=0; indexp<lenp; ++indexp)
  643.         prod[indexp] = '0';
  644.     while (index2 >= 0)
  645.         {
  646.         indexp = lenp + index2 - len2;
  647.         if (num2[index2] == '0')
  648.             {
  649.             carry = 0;
  650.             indexp -= len1;
  651.             }
  652.         else
  653.             {
  654.             index1 = len1 - 1;
  655.             carry = 0;
  656.             while (index1 >= 0)
  657.                 {
  658.                 temp1 = num1[index1] - '0';
  659.                 temp2 = num2[index2] - '0';
  660.                 tempp = prod[indexp] - '0';
  661.                 mult = carry + temp1*temp2 + tempp;
  662.                 prod[indexp] = mult % 10 + '0';
  663.                 carry = mult / 10;
  664.                 --index1;
  665.                 --indexp;
  666.                 }
  667.             }
  668.         prod[indexp] = carry + '0';
  669.         --index2;
  670.         }
  671.     while ((prod[0]=='0') && (lenp>1))
  672.         {
  673.         for (indexp=1; indexp<lenp; ++indexp)
  674.             prod[indexp-1] = prod[indexp];
  675.         --lenp;
  676.         }
  677.     prod[lenp] = '\0';
  678.     return lenp;        
  679.     }
  680.     
  681. /* sdiv() yields quot[] and rem[],     
  682.  * lenq <= max(len1-len2, 1) 
  683.  * lenr <= len2
  684.  */
  685. sdiv(num1, len1, num2, len2, quot, rem)    
  686.     char num1[], num2[], quot[], rem[];
  687.     int len1, len2;
  688.     {
  689.     int lenq, lenr, div, flag, scale,
  690.         index, index1, index2, indexq, indexr, 
  691.         temp1, temp2, temp3, temp4, temp5, qtest;
  692.  
  693.     if (num1[0] != '0')
  694.         {
  695.         for (index1=len1; index1>0; --index1)
  696.             num1[index1] = num1[index1-1];
  697.         num1[0] = '0';
  698.         ++len1;
  699.         }
  700.     while ((num2[0]=='0') && (len2>1))
  701.         {
  702.         for (index2=1; index2<len2; ++index2)
  703.             num2[index2-1] = num2[index2];
  704.         --len2;
  705.         }
  706.     lenq = MAX(len1-len2, 1);
  707.     lenr = len2;
  708.     if ((len1<len2) || ((len1==len2) && (num1[0]<num2[0])))
  709.         {
  710.         quot[0] = '0';
  711.         lenq = 1;
  712.         strcpy(rem, num1);
  713.         lenr = len1;
  714.         }
  715.     if(num2[0] != '0')
  716.         {
  717.         for (indexq=0; indexq<lenq; ++indexq)
  718.             quot[indexq] = '0';
  719.         for (indexr=0; indexr<lenr; ++indexr)
  720.             rem[indexr] = '0';
  721.         flag = 0;
  722.         for (index1=1; index1<len1; ++index1)
  723.             if (num1[index1] != '0')
  724.                 {
  725.                 flag = 1;
  726.                 break;
  727.                 }
  728.         if (flag != 0)
  729.             {
  730.             temp1 = num2[0] - '0';
  731.             scale = 10 / (temp1 + 1);
  732.             if (scale > 1)
  733.                 {
  734.                 flag = 0;
  735.                 index1 = len1 -1;
  736.                 while (index1 >= 0)
  737.                     {
  738.                     temp1 = num1[index1] - '0';
  739.                     div = flag + scale*temp1;
  740.                     num1[index1] = div % 10 + '0';
  741.                     flag = div /10;
  742.                     --index1;
  743.                     }
  744.                 flag = 0;
  745.                 index2 = len2 -1;
  746.                 while (index2 >= 0)
  747.                     {
  748.                     temp1 = num2[index2] - '0';
  749.                     div = flag + scale*temp1;
  750.                     num2[index2] = div % 10 + '0';
  751.                     flag = div / 10;
  752.                     --index2;
  753.                     }
  754.                 }
  755.             index1 = 0;
  756.             while (index1 < (len1-len2))
  757.                 {
  758.                 if (num2[0] == num1[index1])
  759.                     qtest = 9;
  760.                 else
  761.                     {
  762.                     temp1 = num1[index1] - '0';
  763.                     temp3 = num2[0] - '0';
  764.                     if ((index1+1) < len1)
  765.                         temp2 = num1[index1+1] - '0';
  766.                     else
  767.                         temp2 = 0;
  768.                     qtest = (10*temp1 + temp2) / temp3;
  769.                     }
  770.                 temp2 = num1[index1] - '0';
  771.                 temp4 = num2[0] - '0';
  772.                 if (len2 >= 2)
  773.                     temp1 = num2[1] - '0';
  774.                 else
  775.                     temp1 = 0;
  776.                 if ((index1+1) < len1)
  777.                     {
  778.                     temp3 = num1[index1+1] - '0';
  779.                     if ((index1+2) < len1)
  780.                         temp5 = num1[index1+2] - '0';
  781.                     else
  782.                         temp5 = 0;
  783.                     }
  784.                 else
  785.                     {
  786.                     temp3 = 0;
  787.                     temp5 = 0;
  788.                     }                
  789.                 while (qtest*temp1 > (10*(10*temp2 + temp3 
  790.                                     - qtest*temp4) + temp5))
  791.                     --qtest;
  792.                 index2 = len2 - 1;
  793.                 index = index1 + len2;
  794.                 flag = 0;
  795.                 while (index >= index1)
  796.                     {
  797.                     if (index2 >= 0)
  798.                         {
  799.                         temp1 = num2[index2] - '0';
  800.                         flag -= qtest*temp1;
  801.                         }
  802.                     temp1 = num1[index] - '0';
  803.                     div = flag + temp1;
  804.                     if (div < 0)
  805.                         {
  806.                         flag = div / 10;
  807.                         div %= 10;
  808.                         if (div < 0)
  809.                             {
  810.                             div += 10;
  811.                             --flag;
  812.                             }
  813.                         }
  814.                     else
  815.                         flag = 0;
  816.                     num1[index] = div + '0';
  817.                     --index2;
  818.                     --index;
  819.                     }
  820.                 indexq = lenq - (len1 - len2) + index1;   
  821.                 if (flag != 0)
  822.                     {
  823.                     quot[indexq] = qtest - 1 + '0';
  824.                     index2 = len2 - 1;
  825.                     index = index1 + len2;
  826.                     flag = 0;
  827.                     while (index >= index1)
  828.                         {
  829.                         if (index2 >= 0)
  830.                             {
  831.                             temp1 = num2[index2] - '0';
  832.                             flag += temp1;
  833.                             }
  834.                         temp1 = num1[index] - '0';
  835.                         div = flag + temp1;
  836.                         if (div > 9)
  837.                             {
  838.                             div -= 10;
  839.                             flag = 1;
  840.                             }
  841.                         else
  842.                             flag = 0;
  843.                         num1[index] = div + '0';
  844.                         --index2;
  845.                         --index;
  846.                         }
  847.                     }
  848.                 else
  849.                     quot[indexq] = qtest + '0';
  850.                 ++index1;
  851.                 }
  852.             index1 = len1 - len2;
  853.             indexr = lenr - len2;
  854.             flag = 0;
  855.             while (index1 < len1)
  856.                 {
  857.                 temp1 = num1[index1] - '0';
  858.                 div = temp1 + 10*flag;
  859.                 rem[indexr] = div / scale + '0';
  860.                 flag = div % scale;
  861.                 ++index1;
  862.                 ++indexr;
  863.                 }
  864.             index2 = 0;
  865.             flag = 0;
  866.             while (index2 < len2)
  867.                 {
  868.                 temp1 = num2[index2] - '0';
  869.                 div = temp1 + 10*flag;
  870.                 num2[index2] = div / scale + '0';
  871.                 flag = div % scale;
  872.                 ++index2;
  873.                 }
  874.             }
  875.         while ((quot[0]=='0') && (lenq>1))
  876.             {
  877.             for (indexq=1; indexq<lenq; ++indexq)
  878.                 quot[indexq-1] = quot[indexq];
  879.             --lenq;
  880.             }
  881.         while ((rem[0]=='0') && (lenr>1))
  882.             {
  883.             for (indexr=1; indexr<lenr; ++indexr)
  884.                 rem[indexr-1] = rem[indexr];
  885.             --lenr;
  886.             }
  887.         quot[lenq] = '\0';
  888.         rem[lenr] = '\0';
  889.         }
  890.     else
  891.         {
  892.         quot[0] = '\0';
  893.         rem[0] = '\0';
  894.         return 0;
  895.         }
  896.     return (lenq+lenr) * (lenq>0) * (lenr>0);
  897.     }
  898.  
  899. /*    parse() returns 0 on error.
  900.  *    input:    str[] a string of digits with optional decimal point
  901.  *            and leading sign.
  902.  *    output:    num[] is a string containing the significant digits
  903.  *            of str[], and digl/digr is the number of digits to the
  904.  *          left/right of the decimal point.
  905.  */    
  906. parse(str, num, sign, digl, digr)
  907.     char str[], num[];
  908.     int *sign, *digl, *digr;
  909.     {
  910.     char c;
  911.     int dflag, istr, inum, len;
  912.  
  913.     dflag = 0;
  914.     inum = 0;
  915.     *digl = 0;
  916.     *digr = 0;
  917.     c = str[0];
  918.     if (c=='+')
  919.         *sign = 1;
  920.     else if (c=='-')
  921.         *sign = -1;
  922.     else if (c=='.')
  923.         {
  924.         *sign = 1;
  925.         dflag = 1;
  926.         }
  927.     else if ((c>='0') && (c<='9'))
  928.         {
  929.         *sign = 1;
  930.         if (c != '0')
  931.             {
  932.             *digl = 1;
  933.             num[0] = c;
  934.             ++inum;
  935.             }
  936.         }
  937.     else
  938.         return (0);
  939.     istr = 1;
  940.     while ((c=str[istr++]) != '\0')
  941.         {
  942.         if ((c=='.') && (dflag==0))
  943.             dflag = 1;
  944.         else if ((c>='0') && (c<='9'))
  945.             {
  946.             if ((c!='0') || (*digl>0) || (dflag==1))
  947.                 {
  948.                 if (dflag==0)
  949.                     ++(*digl);
  950.                 else
  951.                     ++(*digr);
  952.                 num[inum] = c;
  953.                 ++inum;
  954.                 }
  955.             }
  956.         else
  957.             return (0);
  958.         }
  959.     --inum;
  960.       while ((num[inum]=='0') && (inum>= *digl))
  961.         {
  962.         --(*digr);
  963.         --inum;
  964.         }
  965.     num[++inum] = '\0';
  966.     len = inum;
  967.     while ((num[0]=='0') && (len>1))
  968.         {
  969.         for (inum=1; inum<len; ++inum)
  970.             num[inum-1] = num[inum];
  971.         --len;
  972.         if (*digl>0)
  973.             --(*digl);
  974.         }
  975.     num[len] = '\0';
  976.     return (1);
  977.     }
  978.  
  979. /*    fix()
  980.  *    inserts sign and decimal point in digit string num[]
  981.  */
  982. fix(num, len, sign, digr)
  983.     char num[];
  984.     int len, sign, digr;
  985.     {
  986.     int inum;
  987.     char nnum[N+3];
  988.  
  989.     if (digr >= 0)
  990.         {
  991.         if (len >= digr)
  992.             {
  993.             for (inum=len; inum>len-digr; --inum)
  994.                 num[inum] = num[inum-1];
  995.             num[inum] = '.';
  996.             ++len;
  997.             num[len] = '\0';
  998.             }
  999.         else
  1000.             {
  1001.             nnum[0] = '.';
  1002.             for (inum=1; inum<=digr; ++inum)
  1003.                 {
  1004.                 if (inum<=digr-len)
  1005.                     nnum[inum] = '0';
  1006.                 else
  1007.                     nnum[inum] = num[inum-digr+len-1];
  1008.                 }
  1009.             nnum[inum] = '\0';
  1010.             strcpy(num, nnum);
  1011.             len = digr+1;
  1012.             }
  1013.         }
  1014.     else
  1015.         {
  1016.         len -= digr - 1;
  1017.         pad(num, -digr);
  1018.         num[len-1] = '.';
  1019.         num[len] = '\0';
  1020.  
  1021.         }
  1022.     if (sign==-1)
  1023.         {
  1024.         for (inum=len; inum>0; --inum)
  1025.             num[inum] = num[inum-1];
  1026.         num[0] = '-';
  1027.         ++len;
  1028.         num[len] = '\0';
  1029.         }
  1030.  
  1031.     }
  1032.  
  1033. /*     pad() 
  1034.  *  input:    num[] a string .
  1035.  *            dig a number of '0's to be appended to num[].
  1036.  *    output: num[] with dig '0's appended.
  1037.  */
  1038.  pad(num, dig)
  1039.      char num[];
  1040.      int dig;
  1041.      {
  1042.      int inum, len;
  1043.  
  1044.     len = strlen(num);
  1045.     for (inum=len; inum < len+dig; ++inum)
  1046.         num[inum] = '0';
  1047.     num[inum] = '\0';
  1048.     }
  1049.  
  1050. /*------------------end of file----------------------*/
  1051.  
  1052.